package com.yk.i_wms.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yk.i_wms.common.model.CheckWarehouseEnum;
import com.yk.i_wms.common.model.Result;
import com.yk.i_wms.dto.SmsOutStockDocDTO;
import com.yk.i_wms.mapper.SmsOutStockDocMapper;
import com.yk.i_wms.model.*;
import com.yk.i_wms.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 出库单
 *
 * @author hbq
 * @date 2021-04-07 14:20:31
 */
@Slf4j
@Service
public class SmsOutStockDocServiceImpl extends ServiceImpl<SmsOutStockDocMapper, SmsOutStockDoc> implements ISmsOutStockDocService {
    @Resource
    private SmsOutStockDocMapper smsOutStockDocMapper;
    @Autowired
    private ISmsOutStockDocDetailService smsOutStockDocDetailService;
    @Autowired
    private ISmsStockInfoService smsStockInfoService;
    @Autowired
    private ISmsOutStockDocRecordService smsOutStockDocRecordService;
    @Autowired
    private ISmsLightColorService smsLightColorService;
    @Autowired
    private IPdtReplaceItemService pdtReplaceItemService;
    @Autowired
    private IUmsItemService umsItemService;
    @Autowired
    private IUmsMsdRuleService umsMsdRuleService;
    @Autowired
    private ISmsStockOperationLogService smsStockOperationLogService;
    /**
     * 列表
     * @param params
     * @return
     */
    public Page<Map> findList(Map<String, Object> params){
        Integer pageNum = MapUtils.getInteger(params, "pageNum");
        Integer pageSize = MapUtils.getInteger(params, "pageSize");
        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = -1;
        }
        Page<Map> pages = new Page<>(pageNum, pageSize);
        return smsOutStockDocMapper.findList(pages, params);
    }

    @Override
    public Result saveAll(SmsOutStockDocDTO smsOutStockDocDTO) {
        SmsOutStockDoc smsOutStockDoc=smsOutStockDocDTO;
        if (smsOutStockDoc.getDocState()!=1){
            return Result.failed("非新建状态不允许修改");
        }
        log.info("新建或更新备料单：{}",smsOutStockDocDTO);
        String docNo =StrUtil.isBlank(smsOutStockDocDTO.getDocNo())?getNewNo(smsOutStockDocDTO.getDocType()):smsOutStockDocDTO.getDocNo();
        smsOutStockDoc.setDocNo(docNo);
        //删除原有docNo的详情
        smsOutStockDocDetailService.remove(new LambdaQueryWrapper<SmsOutStockDocDetail>().eq(SmsOutStockDocDetail::getDocNo,docNo));
        List<SmsOutStockDocDetail> smsOutStockDocDetails = smsOutStockDocDTO.getSmsOutStockDocDetails();
        if (smsOutStockDocDetails == null||smsOutStockDocDetails.isEmpty()) {
            return Result.failed(  "详情列表不能为空");
        }
        smsOutStockDocDetails.forEach(u->{
            u.setDocNo(docNo);
        });
        saveOrUpdate(smsOutStockDoc);
        smsOutStockDocDetailService.saveBatch(smsOutStockDocDetails);

        return Result.succeed("保存成功");
    }

    @Override
    public Result close(SmsOutStockDoc smsOutStockDoc) {
        String docNo = smsOutStockDoc.getDocNo();
        int receiveDetailTotal = smsOutStockDocDetailService.count(new LambdaQueryWrapper<SmsOutStockDocDetail>().eq(SmsOutStockDocDetail::getDocNo, docNo));
        int receivedCount = smsOutStockDocDetailService.count(new LambdaQueryWrapper<SmsOutStockDocDetail>().eq(SmsOutStockDocDetail::getDocNo, docNo).last("and plan_qty=real_qty"));
        /*if (receiveDetailTotal<receivedCount){
            return Result.failed("实收数量不符");
        }*/
        SmsOutStockDoc outStockDoc = getOne(new LambdaQueryWrapper<SmsOutStockDoc>().eq(SmsOutStockDoc::getDocNo, docNo));
        outStockDoc.setDocState(3);
        updateById(outStockDoc);
        return Result.succeed("关结成功");
    }

    @Override
    public Result delete(Map<String, List<Long>> map) {
        List<Long> ids = map.get("ids");
        for (Long id : ids) {
            SmsOutStockDoc outStockDoc = getById(id);
            String docNo = outStockDoc.getDocNo();
            removeById(id);
            smsOutStockDocDetailService.remove(new LambdaQueryWrapper<SmsOutStockDocDetail>()
                    .eq(SmsOutStockDocDetail::getDocNo,docNo)
            );
            smsOutStockDocRecordService.remove(new LambdaQueryWrapper<SmsOutStockDocRecord>()
                .eq(SmsOutStockDocRecord::getDocNo,docNo)
            );
        }
        return Result.succeed("删除成功");
    }

    @Override
    public Result lightUp(Map<String, Object> params) {
        //亮灯程序
        List<SmsLightColor> lightColors = smsLightColorService.list(new LambdaQueryWrapper<SmsLightColor>()
                .eq(SmsLightColor::getState, 0)
                .orderByAsc(SmsLightColor::getSort)
        );
        if (lightColors.isEmpty()){
            return Result.failed("暂无可用灯");
        }
        SmsLightColor smsLightColor = lightColors.get(0);

        //添加物料信息
        String docNo = MapUtil.getStr(params, "docNo");
        String createName = MapUtil.getStr(params, "createName");
        SmsOutStockDoc stockDoc = getOne(new LambdaQueryWrapper<SmsOutStockDoc>().eq(SmsOutStockDoc::getDocNo, docNo));
        List<SmsOutStockDocDetail> outStockDocDetails = smsOutStockDocDetailService.list(new LambdaQueryWrapper<SmsOutStockDocDetail>()
                .eq(SmsOutStockDocDetail::getDocNo, docNo)
        );
        if (stockDoc==null||outStockDocDetails.isEmpty()){
            return Result.failed("无此单号");
        }
        //更新入库单亮灯数据
        stockDoc.setColorCode(smsLightColor.getColorCode());
        stockDoc.setColorName(smsLightColor.getColorName());
        updateById(stockDoc);
        //将该灯色资源占用
        smsLightColor.setState(1);
        smsLightColorService.updateById(smsLightColor);
        List<SmsOutStockDocRecord> outStockDocRecords = smsOutStockDocRecordService.list(new LambdaQueryWrapper<SmsOutStockDocRecord>()
                .eq(SmsOutStockDocRecord::getDocNo, docNo)
        );
        if (outStockDocRecords.isEmpty()){
            //首次生成该入库单亮灯记录
            Integer isAllowReplace = stockDoc.getIsAllowReplace();
            if(isAllowReplace==0){
                //不允许替代料，只需要添加库存中已经有的相应物料到入库记录
                for (SmsOutStockDocDetail smsOutStockDocDetail : outStockDocDetails) {
                    String itemCode = smsOutStockDocDetail.getItemCode();
                    UmsItem umsItem = umsItemService.getOne(new LambdaQueryWrapper<UmsItem>().eq(UmsItem::getItemCode, itemCode));
                    String msdCode = umsItem.getMsdCode();
                    Long planQty = smsOutStockDocDetail.getPlanQty();
                    Long realQty = smsOutStockDocDetail.getRealQty();
                    //该料号的库存时间升序
                    List<SmsStockInfo> stockInfos = smsStockInfoService.list(new LambdaQueryWrapper<SmsStockInfo>()
                            .eq(SmsStockInfo::getItemCode, itemCode)
                            .eq(SmsStockInfo::getWarehouse,CheckWarehouseEnum.S_3.getWarehouse())
                            .eq(SmsStockInfo::getStockState, 1)
                            .orderByAsc(SmsStockInfo::getId)
                    );
                    int size=stockInfos.size();
                    //去除备料记录中已经出现过的sn,去除超期物料，去除暴露时长大于最大暴露时长物料
                    for (int i=0;i<size;i++) {
                        SmsStockInfo stockInfo = stockInfos.get(i);
                        String sn = stockInfo.getSn();
                        SmsOutStockDocRecord stockDocRecord = smsOutStockDocRecordService.getOne(new LambdaQueryWrapper<SmsOutStockDocRecord>()
                                .eq(SmsOutStockDocRecord::getSn, sn)
                                .eq(SmsOutStockDocRecord::getState,1)
                        );
                        int compare = DateUtil.compare(stockInfo.getTimeoutDate(), new Date());
                        if (msdCode != null) {
                            UmsMsdRule msdRule = umsMsdRuleService.getOne(new LambdaQueryWrapper<UmsMsdRule>().eq(UmsMsdRule::getMsdCode, msdCode));
                            if (stockInfo.getBakeTimes()>msdRule.getMaxBakeTimes()){
                                stockInfos.remove(stockInfo);
                                size--;
                            }
                        }
                        if (stockDocRecord != null|| compare<0) {
                            stockInfos.remove(stockInfo);
                            size--;
                        }
                    }
                    List<SmsOutStockDocRecord> stockDocRecords=new ArrayList<>();
                    //计算备料数量
                    if (!stockInfos.isEmpty()){
                        for (SmsStockInfo stockInfo : stockInfos) {
                            Long snQty = stockInfo.getQty();
                            //只要计划数量大于实收数量，继续累加，并保存料盘数据到备料记录表中
                            if (planQty>realQty){
                                SmsOutStockDocRecord stockDocRecord = new SmsOutStockDocRecord();
                                stockDocRecord.setDocNo(docNo);
                                stockDocRecord.setDdId(smsOutStockDocDetail.getId());
                                stockDocRecord.setWoNo(smsOutStockDocDetail.getWoNo());
                                stockDocRecord.setSn(stockInfo.getSn());
                                stockDocRecord.setItemCode(stockInfo.getItemCode());
                                stockDocRecord.setItemName(stockInfo.getItemName());
                                stockDocRecord.setQty(snQty);
                                stockDocRecord.setAreaSn(stockInfo.getAreaSn());
                                stockDocRecord.setState(1);
                                stockDocRecord.setCreateName(createName);
                                stockDocRecords.add(stockDocRecord);
                                realQty=realQty+snQty;
                            }
                        }
                        //批量新增备料记录
                        smsOutStockDocRecordService.saveBatch(stockDocRecords);
                    }
                    //更新缺料数量
                    Long shortQty = planQty - realQty<0?0:planQty-realQty;
                    smsOutStockDocDetail.setShortQty(shortQty);
                    smsOutStockDocDetailService.updateById(smsOutStockDocDetail);
                }
            }
            if(isAllowReplace==1){
                //需要替代料时
                for (SmsOutStockDocDetail smsOutStockDocDetail : outStockDocDetails) {
                    String itemCode = smsOutStockDocDetail.getItemCode();
                    UmsItem umsItem = umsItemService.getOne(new LambdaQueryWrapper<UmsItem>().eq(UmsItem::getItemCode, itemCode));
                    String msdCode = umsItem.getMsdCode();
                    Long planQty = smsOutStockDocDetail.getPlanQty();
                    Long realQty = smsOutStockDocDetail.getRealQty();
                    //该料号的库存时间升序
                    List<SmsStockInfo> stockInfos = smsStockInfoService.list(new LambdaQueryWrapper<SmsStockInfo>()
                            .eq(SmsStockInfo::getItemCode, itemCode)
                            .eq(SmsStockInfo::getWarehouse,CheckWarehouseEnum.S_3.getWarehouse())
                            .eq(SmsStockInfo::getStockState, 1)
                            .orderByAsc(SmsStockInfo::getId)
                    );
                    //去除备料记录中已经出现过的sn,去除超期物料，去除暴露时长大于最大暴露时长物料
                    int size=stockInfos.size();
                    for (int i=0;i<size;i++) {
                        SmsStockInfo stockInfo = stockInfos.get(i);
                        String sn = stockInfo.getSn();
                        SmsOutStockDocRecord stockDocRecord = smsOutStockDocRecordService.getOne(new LambdaQueryWrapper<SmsOutStockDocRecord>()
                                .eq(SmsOutStockDocRecord::getSn, sn)
                                .eq(SmsOutStockDocRecord::getState,1)
                        );
                        if (msdCode != null) {
                            UmsMsdRule msdRule = umsMsdRuleService.getOne(new LambdaQueryWrapper<UmsMsdRule>().eq(UmsMsdRule::getMsdCode, msdCode));
                            if (stockInfo.getBakeTimes()>msdRule.getMaxBakeTimes()){
                                stockInfos.remove(stockInfo);
                                size--;
                            }
                        }
                        int compare = DateUtil.compare(stockInfo.getTimeoutDate(), new Date());
                        if (stockDocRecord != null|| compare<0) {
                            stockInfos.remove(stockInfo);
                            size--;
                        }
                    }
                    List<SmsOutStockDocRecord> stockDocRecords=new ArrayList<>();
                    //计算备料数量
                    if (!stockInfos.isEmpty()){
                        for (SmsStockInfo stockInfo : stockInfos) {
                            Long snQty = stockInfo.getQty();
                            //只要计划数量大于实收数量，继续累加，并保存料盘数据到备料记录表中
                            if (planQty>realQty){
                                SmsOutStockDocRecord stockDocRecord = new SmsOutStockDocRecord();
                                stockDocRecord.setDocNo(docNo);
                                stockDocRecord.setDdId(smsOutStockDocDetail.getId());
                                stockDocRecord.setWoNo(smsOutStockDocDetail.getWoNo());
                                stockDocRecord.setSn(stockInfo.getSn());
                                stockDocRecord.setItemCode(stockInfo.getItemCode());
                                stockDocRecord.setItemName(stockInfo.getItemName());
                                stockDocRecord.setQty(snQty);
                                stockDocRecord.setAreaSn(stockInfo.getAreaSn());
                                stockDocRecord.setState(1);
                                stockDocRecord.setCreateName(createName);
                                stockDocRecords.add(stockDocRecord);
                                realQty=realQty+snQty;
                            }
                        }
                    }
                    //当计算到的实收数量未达到计划数量时，寻找其替代料，并修改入库详情表
                    long requireQty = planQty - realQty;
                    if(requireQty>0){
                        //补充缺料数量
                        smsOutStockDocDetail.setShortQty(planQty-realQty);
                        List<PdtReplaceItem> pdtReplaceItems=pdtReplaceItemService.getGroupItemListByItemCode(itemCode,1);
                        if (!pdtReplaceItems.isEmpty()){
                            for (PdtReplaceItem pdtReplaceItem : pdtReplaceItems) {
                                String replaceItemCode = pdtReplaceItem.getItemCode();
                                List<SmsStockInfo> replaceStockInfos = smsStockInfoService.list(new LambdaQueryWrapper<SmsStockInfo>()
                                        .eq(SmsStockInfo::getItemCode, replaceItemCode)
                                        .eq(SmsStockInfo::getWarehouse,CheckWarehouseEnum.S_3.getWarehouse())
                                        .eq(SmsStockInfo::getStockState, 1)
                                        .orderByAsc(SmsStockInfo::getId)
                                );
                                int replaceSize=replaceStockInfos.size();

                                //去除备料记录中已经出现过的sn,去除超期物料，去除暴露时长大于最大暴露时长物料
                                for (int i=0;i<replaceSize;i++) {
                                    SmsStockInfo replaceStockInfo=replaceStockInfos.get(i);
                                    String sn = replaceStockInfo.getSn();
                                    SmsOutStockDocRecord stockDocRecord = smsOutStockDocRecordService.getOne(new LambdaQueryWrapper<SmsOutStockDocRecord>()
                                            .eq(SmsOutStockDocRecord::getSn, sn)
                                            .eq(SmsOutStockDocRecord::getState,1)
                                    );
                                    if (msdCode != null) {
                                        UmsMsdRule msdRule = umsMsdRuleService.getOne(new LambdaQueryWrapper<UmsMsdRule>().eq(UmsMsdRule::getMsdCode, msdCode));
                                        if (replaceStockInfo.getBakeTimes()>msdRule.getMaxBakeTimes()){
                                            replaceStockInfos.remove(replaceStockInfo);
                                            replaceSize--;
                                        }
                                    }
                                    int compare = DateUtil.compare(replaceStockInfo.getTimeoutDate(), new Date());
                                    if (stockDocRecord != null|| compare<0) {
                                        replaceStockInfos.remove(replaceStockInfo);
                                        replaceSize--;
                                    }
                                }
                                if (!replaceStockInfos.isEmpty()) {
                                    //先创建此详情记录
                                    SmsOutStockDocDetail newSmsOutStockDocDetail = new SmsOutStockDocDetail();
                                    newSmsOutStockDocDetail.setDocNo(docNo);
                                    newSmsOutStockDocDetail.setWoNo(smsOutStockDocDetail.getWoNo());
                                    newSmsOutStockDocDetail.setItemCode(replaceItemCode);
                                    newSmsOutStockDocDetail.setItemName(pdtReplaceItem.getItemName());
                                    newSmsOutStockDocDetail.setModelCode(smsOutStockDocDetail.getModelCode());
                                    newSmsOutStockDocDetail.setModelName(smsOutStockDocDetail.getModelName());
                                    newSmsOutStockDocDetail.setPlanQty(0L);
                                    newSmsOutStockDocDetail.setRealQty(0L);
                                    newSmsOutStockDocDetail.setReplaceGroup(pdtReplaceItem.getReplaceGroup());
                                    smsOutStockDocDetailService.save(newSmsOutStockDocDetail);

                                    for (SmsStockInfo replaceStockInfo : replaceStockInfos) {
                                        //添加替代料的
                                        SmsOutStockDocRecord stockDocRecord = new SmsOutStockDocRecord();
                                        stockDocRecord.setDocNo(docNo);
                                        stockDocRecord.setDdId(newSmsOutStockDocDetail.getId());
                                        stockDocRecord.setWoNo(smsOutStockDocDetail.getWoNo());
                                        stockDocRecord.setSn(replaceStockInfo.getSn());
                                        stockDocRecord.setItemCode(replaceStockInfo.getItemCode());
                                        stockDocRecord.setItemName(replaceStockInfo.getItemName());
                                        stockDocRecord.setQty(replaceStockInfo.getQty());
                                        stockDocRecord.setAreaSn(replaceStockInfo.getAreaSn());
                                        stockDocRecord.setState(1);
                                        stockDocRecord.setCreateName(createName);
                                        stockDocRecords.add(stockDocRecord);

                                        long newPlanQty =Math.min(newSmsOutStockDocDetail.getPlanQty() + replaceStockInfo.getQty(),requireQty) ;
                                        //更新详情数量
                                        newSmsOutStockDocDetail.setPlanQty(newSmsOutStockDocDetail.getPlanQty()+ newPlanQty);
                                        smsOutStockDocDetailService.updateById(newSmsOutStockDocDetail);
                                        requireQty=requireQty-replaceStockInfo.getQty();
                                        if (requireQty<=0){
                                            break;
                                        }
                                    }
                                }
                                if (requireQty<=0){
                                    break;
                                }
                            }
                            long replaceItemQty=0;
                            //更新缺料数量
                            List<SmsOutStockDocDetail> list = smsOutStockDocDetailService.list(new LambdaQueryWrapper<SmsOutStockDocDetail>()
                                    .eq(SmsOutStockDocDetail::getDocNo, docNo)
                                    .eq(SmsOutStockDocDetail::getReplaceGroup, smsOutStockDocDetail.getReplaceGroup())
                                    .ne(SmsOutStockDocDetail::getItemCode,smsOutStockDocDetail.getItemCode())
                            );
                            for (SmsOutStockDocDetail docDetail : list) {
                                replaceItemQty=docDetail.getPlanQty()+replaceItemQty;
                            }
                            smsOutStockDocDetail.setPlanQty(planQty-replaceItemQty);
                            smsOutStockDocDetail.setShortQty(planQty-replaceItemQty-realQty);
                        }
                    }
                    //批量新增备料记录
                    smsOutStockDocRecordService.saveBatch(stockDocRecords);
                    smsOutStockDocDetailService.updateById(smsOutStockDocDetail);
                }
            }
        }
        return Result.succeed("保存成功");
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result scanSN(Map<String, Object> map) {
        try{
            log.info("扫码备料请求参数{}",map);
            String sn = MapUtil.getStr(map, "sn");
            String createName = MapUtil.getStr(map, "createName");
            String docNo = MapUtil.getStr(map, "docNo");
            Integer docType = MapUtil.getInt(map, "docType");

            SmsOutStockDoc outStockDoc = getOne(new LambdaQueryWrapper<SmsOutStockDoc>().eq(SmsOutStockDoc::getDocNo, docNo));
            if (outStockDoc == null) {
                return Result.failed("无此单号");
            }
            if (!outStockDoc.getDocType().equals(docType)){
                return Result.failed("类型不符");
            }
            SmsOutStockDocRecord record = smsOutStockDocRecordService.getOne(new LambdaQueryWrapper<SmsOutStockDocRecord>()
                    .eq(SmsOutStockDocRecord::getDocNo,docNo)
                    .eq(SmsOutStockDocRecord::getSn, sn)
                    .eq(SmsOutStockDocRecord::getState, 1)
            );
            if (record == null) {
                return Result.failed("条码与单号不符");
            }
            SmsStockInfo stockInfo = smsStockInfoService.getOne(new LambdaQueryWrapper<SmsStockInfo>().eq(SmsStockInfo::getSn, sn));
            if (stockInfo == null) {
                return Result.failed("无此库存");
            }
            if (stockInfo.getStockState() != 1) {
                return Result.failed("非在库状态");
            }
            if (!stockInfo.getWarehouse().equals(CheckWarehouseEnum.S_1.getWarehouse())) {
                return Result.failed("非良品库");
            }
            //修改库存信息
            stockInfo.setStockState(2);
            stockInfo.setWarehouse(CheckWarehouseEnum.S_5.getWarehouse());
            stockInfo.setWhCode("MAL");
            stockInfo.setAreaSn("");
            smsStockInfoService.updateById(stockInfo);

            //修改备料状态
            record.setState(2);
            record.setCreateName(createName);
            smsOutStockDocRecordService.updateById(record);

            //修改详情的数量
            Long ddId = record.getDdId();
            SmsOutStockDocDetail docDetail = smsOutStockDocDetailService.getById(ddId);
            docDetail.setRealQty(docDetail.getRealQty()+stockInfo.getQty());
            smsOutStockDocDetailService.updateById(docDetail);

            //添加操作日志
            SmsStockOperationLog smsStockOperationLog = new SmsStockOperationLog();
            smsStockOperationLog.setSn(sn);
            smsStockOperationLog.setDocNo(stockInfo.getDocNo());
            smsStockOperationLog.setType(CheckWarehouseEnum.S_5.getCheckState());
            smsStockOperationLog.setItemCode(stockInfo.getItemCode());
            smsStockOperationLog.setItemName(stockInfo.getItemName());
            smsStockOperationLog.setWarehouse(stockInfo.getWarehouse());
            smsStockOperationLog.setAreaSn("");
            smsStockOperationLog.setQty(stockInfo.getQty());
            smsStockOperationLog.setCreateName(createName);
            smsStockOperationLogService.save(smsStockOperationLog);
            return Result.succeed("备料成功");
        }
        catch (Exception e){
            // 事务回滚
            log.error("扫码备料异常：",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.failed( e,"保存失败,请联系管理员");
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result scanCancel(Map<String, Object> map) {
        try{
            log.info("扫码取消备料请求参数{}",map);
            String sn = MapUtil.getStr(map, "sn");
            String createName = MapUtil.getStr(map, "createName");
            String docNo = MapUtil.getStr(map, "docNo");
            Integer docType = MapUtil.getInt(map, "docType");

            SmsOutStockDoc outStockDoc = getOne(new LambdaQueryWrapper<SmsOutStockDoc>().eq(SmsOutStockDoc::getDocNo, docNo));
            if (outStockDoc == null) {
                return Result.failed("无此单号");
            }
            if (!outStockDoc.getDocType().equals(docType)){
                return Result.failed("类型不符");
            }
            SmsOutStockDocRecord record = smsOutStockDocRecordService.getOne(new LambdaQueryWrapper<SmsOutStockDocRecord>()
                    .eq(SmsOutStockDocRecord::getDocNo,docNo)
                    .eq(SmsOutStockDocRecord::getSn, sn)
                    .eq(SmsOutStockDocRecord::getState, 2)
            );
            if (record == null) {
                return Result.failed("条码与单号不符");
            }
            SmsStockInfo stockInfo = smsStockInfoService.getOne(new LambdaQueryWrapper<SmsStockInfo>().eq(SmsStockInfo::getSn, sn));
            if (stockInfo == null) {
                return Result.failed("无此库存");
            }
            if (stockInfo.getStockState() != 2) {
                return Result.failed("非备料状态");
            }
            if (!stockInfo.getWarehouse().equals(CheckWarehouseEnum.S_5.getWarehouse())) {
                return Result.failed("非生产库");
            }
            //修改库存信息
            stockInfo.setStockState(1);
            stockInfo.setWarehouse(CheckWarehouseEnum.S_7.getWarehouse());
            smsStockInfoService.updateById(stockInfo);

            //修改备料状态
            record.setState(1);
            record.setCreateName(createName);
            smsOutStockDocRecordService.updateById(record);

            //修改详情的数量
            Long ddId = record.getDdId();
            SmsOutStockDocDetail docDetail = smsOutStockDocDetailService.getById(ddId);
            docDetail.setRealQty(docDetail.getRealQty()-stockInfo.getQty());
            smsOutStockDocDetailService.updateById(docDetail);

            //添加操作日志
            SmsStockOperationLog smsStockOperationLog = new SmsStockOperationLog();
            smsStockOperationLog.setSn(sn);
            smsStockOperationLog.setDocNo(stockInfo.getDocNo());
            smsStockOperationLog.setType(CheckWarehouseEnum.S_7.getCheckState());
            smsStockOperationLog.setItemCode(stockInfo.getItemCode());
            smsStockOperationLog.setItemName(stockInfo.getItemName());
            smsStockOperationLog.setWarehouse(stockInfo.getWarehouse());
            smsStockOperationLog.setAreaSn("");
            smsStockOperationLog.setQty(stockInfo.getQty());
            smsStockOperationLog.setCreateName(createName);
            smsStockOperationLogService.save(smsStockOperationLog);
            return Result.succeed("保存成功");
        }
        catch (Exception e){
            // 事务回滚
            log.error("扫码取消备料异常：",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.failed( e,"保存失败,请联系管理员");
        }
    }

    /**
     * 获取新的串号
     * @return 当前串号的下一个串号
     */
    private String getNewNo(Integer docType){
        //生成新的串号
        String prefix="ME0"+ docType + DateUtil.format(new Date(), "yyyyMMdd");
        String maxNo=prefix+"001";
        SmsOutStockDoc one = getOne(new QueryWrapper<SmsOutStockDoc>()
                .last("where doc_no like '" + prefix + "%' order by doc_no desc limit 1"));
        if (one != null) {
            Long aLong = Convert.toLong(StrUtil.removePrefix(one.getDocNo(), prefix));
            maxNo=prefix+String.format("%3d",aLong+1).replace(" ","0");
        }
        return maxNo;
    }
}
